package com.mh.dto.bo;

import com.mh.pojo.HistoryMessages;
import com.mh.utils.CommonUtil;
import com.mh.utils.ConvertUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Date:2024/9/4
 * author:zmh
 * description: 动态群组管理器，用来管理维护群组和群成员之间的关系。
 * - 当用户向指定群组发送消息后，可以通过此管理器获取redis中群组的所有成员
 * - 的session用于群发。
 * - 当某群组的成员发生变化后，使用此管理器对redis和mysql中数据做同步处理。
 **/

@Component
@RequiredArgsConstructor
public class DynamicGroupManager {

    // Redis 模板，用于操作 Redis 中的群组数据
    private final StringRedisTemplate redisTemplate;

    @Resource
    @Qualifier("redisTemplateSet")
    private RedisTemplate<String, Set<String>> redisTemplateSet;

    private final UserManager userManager;

    /**
     * 将用户加入群组
     * @param groupName 群组名称
     * @param userId    用户 ID
     * @param session   用户的 WebSocket 会话
     */
    public void joinGroup(String groupName, String userId, WebSocketSession session) {
        // 将用户 ID 加入 Redis 的群组 Set 中
        redisTemplate.opsForSet().add(getRedisGroupKey(groupName), userId);
    }

    /**
     * 从群组中移除用户
     *
     * @param groupName 群组名称
     * @param userId    用户 ID
     */
    public void leaveGroup(String groupName, String userId) {
        // 从 Redis 中移除用户
        redisTemplate.opsForSet().remove(getRedisGroupKey(groupName), userId);
    }

    /**
     * 向指定群组发送消息
     * @param historyMessages 构造好的历史消息记录，代表本次的消息内容
     */
    public void sendMessageToGroup(HistoryMessages historyMessages) {
        historyMessages.setId(null);
        // 获取 Redis 中数据：该群组中的所有用户 ID
//        Set<String> userIds = redisTemplate.opsForSet().members(getRedisGroupKey(historyMessages.getReceiver()));
        Set<String> userIds = redisTemplateSet.opsForValue().get("chat-group:" + historyMessages.getReceiver());
        
        if (userIds == null) return;

        // 向群组中的每个用户发送消息
        for (String userId : userIds) {
            WebSocketSession session = userManager.getSessionByUserId(userId);
            if (session != null && session.isOpen()) {
                try {
                    // 将历史消息对象调用JSON转换函数转为JSON发送到前端
                    session.sendMessage(new TextMessage(ConvertUtil.ObjectToJson(historyMessages)));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 生成 Redis 中存储群组用户的 Key
     * @param groupName 群组名称
     * @return Redis Key
     */
    private String getRedisGroupKey(String groupName) {
        return "chat:group:" + groupName;
    }

}
